package handler

import (
	mydb "filestore-server/db"
	"filestore-server/util"
	"fmt"
	"io/ioutil"
	"net/http"
	"time"
)

const (
	pwd_salt = "swes"
	token_salt = "_tokensalt"
)

// SignupHandler 用户注册
func SignupHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method == http.MethodGet {
		// 如果是GET请求，返回注册页面
		// 读取注册页面
		data, err := ioutil.ReadFile("./static/view/signup.html")
		if err != nil {
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
		w.Write(data)
		return
	}

	// 解析参数
	r.ParseForm()
	username := r.Form.Get("username")
	password := r.Form.Get("password")

	if len(username) < 3 || len(password) < 5 {
		w.Write([]byte("参数不合法"))
		return
	}

	// 密码+加盐 并且 sha1 加密
	enc_password := util.Sha1([]byte(password + pwd_salt))
	suc := mydb.UserSignup(username, enc_password)
	if suc {
		w.Write([]byte("SUCCESS"))
	} else {
		w.Write([]byte("ERROR"))
	}
}

// SigninHandler 用户登陆
func SigninHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method == http.MethodGet {
		data, _ := ioutil.ReadFile("./static/view/signin.html")
		w.Write(data)
		return
	}

	r.ParseForm()
	username := r.Form.Get("username")
	password := r.Form.Get("password")

	encPassword := util.Sha1([]byte(password + pwd_salt))
	// 1.效验用户和密码
	pwdChecked := mydb.UserSignin(username, encPassword)
	if !pwdChecked {
		w.Write([]byte("用户名或密码错误"))
		return
	}

	// 2.生成访问凭证（Token）
	token := GenToken(username)
	upRes := mydb.UploadToken(username, token)
	if !upRes {
		w.Write([]byte("生成Token失败！"))
		return
	}

	// 3.登陆成功后重定向到首页
	// w.Write([]byte("http://" + r.Host + "/static/view/home.html"))

	resp := util.RespMsg{
		Code: 0,
		Msg:  "OK",
		Data: struct {
			Location string
			Username string
			Token string
		}{ // 表示直接初始化这个 struct
			Location: "http://" + r.Host + "/static/view/home.html",
			Username: username,
			Token: token,
		},
	}

	// 响应数据
	w.Write(resp.JSONBytes())

}

// 生成Token
func GenToken(username string) string {
	// 40位的Token： md5(username + timestamp + token_sal) + timestamp[:8]

	// 获取当前时间
	ts := fmt.Sprintf("%x", time.Now())
	tokenPrefix := util.MD5([]byte(username + ts + token_salt))

	return tokenPrefix + ts[:8]
}

// 验证Token
func IsTokenValid(token string) bool {
	if len(token) != 40 {
		return false
	}
	// TODO 判断token的时效性，是否过期
	// TODO 数据库是否存在对应token信息
	// TODO 对比两个token是否一致

	return true

}

// UserInfoHandler 获取用户信息
func UserInfoHandler(w http.ResponseWriter, r *http.Request) {
	// 1.解析请求信息
	r.ParseForm()
	username := r.Form.Get("username")

	// 因为增加了 HTTPInterceptor 拦截器
	//token := r.Form.Get("token")
	// 2.验证token是否有效
	//isValidToken := IsTokenValid(token)
	//if !isValidToken {
	//	w.WriteHeader(http.StatusForbidden)
	//	return
	//}

	// 3.查询用户信息
	user, err := mydb.GetUserInfo(username)
	if err != nil {
		w.WriteHeader(http.StatusForbidden)
		return
	}

	// 4.组装并且响应用户数据
	resp := util.RespMsg{
		Code: 0,
		Msg:  "OK",
		Data: user,
	}

	w.Write(resp.JSONBytes())
}